//
// A Simple Game Engine
//
// Copyright 2009 CG & CAD Institute, Tsinghua University.
// All rights reserved.
//

#include "gameengine.h"
#include "game.h"

// C++ headers
//#include <iostream>

// C headers
//#include <stdio.h>

// User headers
//#include "my_header.h"

namespace engine
{

GameEngine::GameEngine(void)
{
    _sleep = false;
}

GameEngine::~GameEngine(void)
{
    // TODO:
}

bool GameEngine::Initialize(int width, int height, int bpp, std::string title, int frame)
{
    _width = width;
    _height = height;
    _bpp = bpp;
    _title = title;
    _frame = frame;

    _screen = SDL_SetVideoMode( _width, _height, _bpp, SDL_SWSURFACE );

    if( _screen == NULL )
        return false;

    SDL_WM_SetCaption( _title.c_str(), NULL );

    return true;
}

GameEngine* GameEngine::GetInstance()
{
    if (_gameEngine == NULL)
        _gameEngine = new GameEngine();
    return _gameEngine;
}

void GameEngine::Main()
{
    Timer fps;
    bool quit = false;

    while( quit == false )
    {
        fps.start();

        while( SDL_PollEvent( &_event ) )
        {
            HandleEvent(_event);

            if( _event.type == SDL_QUIT )
            {
                quit = true;
            }
        }

        if (!_sleep)
        {
            GameCycle();
        }

        if( fps.get_ticks() < 1000 / _frame )
        {
            SDL_Delay( ( 1000 / _frame ) - fps.get_ticks() );
        }
    }
}

void GameEngine::AddSprite(Sprite* sprite)
{
    if (sprite != NULL)
    {
        _sprites.push_back(sprite);
    }
}

void GameEngine::DrawSprite()
{
    SDL_FillRect( _screen, &_screen->clip_rect, SDL_MapRGB( _screen->format, 0x0, 0x0, 0x0 ) );

    std::vector<Sprite*>::iterator pos;
    for (pos=_sprites.begin(); pos!=_sprites.end(); ++pos)
        (*pos)->Draw(_screen);
}

bool GameEngine::UpdateSurface()
{
    if( SDL_Flip( _screen ) == -1 )
    {
        return false;
    }

    return true;
}

void GameEngine::UpdateSprite()
{
    std::vector<Sprite*>::iterator pos;
    for (pos=_sprites.begin(); pos!=_sprites.end(); ++pos)
        (*pos)->Update();
}

void GameEngine::CleanSprite()
{
    std::vector<Sprite*>::iterator pos;
    for (pos=_sprites.begin(); pos!=_sprites.end(); ++pos)
        delete *pos;
    _sprites.clear();
}

Sprite* GameEngine::IsPointInSprite(int x, int y)
{
}

bool GameEngine::CheckSpriteCollision(Sprite* testSprite)
{
    std::vector<Sprite*>::iterator pos;
    for (pos=_sprites.begin(); pos!=_sprites.end(); ++pos)
    {
        if (testSprite == *pos)
            continue;

        if (testSprite->TestCollision(*pos))
            return SpriteCollision((*pos), testSprite);
    }

    return false;
}

int GameEngine::GetWidth()
{
    return _width;
}

int GameEngine::GetHeight()
{
    return _height;
}

void GameEngine::SetSleep(bool sleep)
{
    _sleep = sleep;
}

bool GameEngine::GetSleep()
{
    return _sleep;
}

} // namespace engine
